/*
 * Copyright 2016 czy1121
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jcp.baselibrary.base;

import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.ProgressBar;

import com.jcp.baselibrary.R;
import com.jcp.baselibrary.dialog.CustomDialog;
import com.jcp.baselibrary.dialog.DialogHelper;
import com.jcp.baselibrary.dialog.LoadingDialog;
import com.jcp.baselibrary.networkstate.NetworkUtil;
import com.jcp.baselibrary.okhttp3.OkHttpUtil;
import com.jcp.baselibrary.okhttp3.OkRequestParams;
import com.jcp.baselibrary.okhttp3.response.OkHttpResFileHandler;
import com.jcp.baselibrary.okhttp3.response.OkHttpResJsonHandler;
import com.jcp.baselibrary.utils.MyLogger;
import com.jcp.baselibrary.utils.TDevice;
import com.jcp.baselibrary.utils.UIUtils;

import org.json.JSONObject;

import java.io.File;

import okhttp3.Headers;

/**
 * =========================================================
 * @ProjectName: 
 * @ClassName: CheckUpdateManager
 * @Description: 
 * @Author: jincp
 * @CreateDate: 2019/3/14 14:50
 * =========================================================
 */
public class CheckUpdateManager {

    public static int NOTIFY_ID = 0x999;

    private LoadingDialog mWaitDialog;
    private static CheckUpdateManager INSTANCE;
    private UpdateManagerConfig mConfig;
    private UpdateInformation updateInformation;

    private CheckUpdateManager(UpdateManagerConfig config) {
        this.mConfig = config;
        OkHttpUtil.init(null);
        if (config.mIsShowWaitDialog) {
            mWaitDialog = DialogHelper.getCustomWaitDialog(config.mActivity);
            mWaitDialog.setMessage("正在检查中...");
        }
    }

    private static CheckUpdateManager newInstance(UpdateManagerConfig config) {
        if (INSTANCE == null) {
            synchronized (CheckUpdateManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new CheckUpdateManager(config);
                }
            }
        }
        return INSTANCE;
    }

    public static CheckUpdateManager getInstance() {
        return INSTANCE;
    }

    public void checkUpdateVersion() {
        if (TextUtils.isEmpty(mConfig.mCheckUrl)){
            return;
        }
        MyLogger.d("CheckUpdateManager", mConfig.mCheckUrl);
        if (mConfig.mIsShowProgressDialog){
            mWaitDialog.show(mConfig.mActivity.getSupportFragmentManager(), "update_dialog");
        }
        OkHttpUtil.post(mConfig.mCheckUrl, new OkRequestParams(), new OkHttpResJsonHandler() {

            @Override
            public void onSuccess(int code, Headers headers, JSONObject response) {
                if (mConfig.mIsShowProgressDialog){
                    mWaitDialog.dismiss();
                }
                updateInformation = mConfig.mParse.parse(response);
                if (updateInformation.isHasNewVersion) {
                    DialogHelper.getOkCancelDialog(mConfig.mActivity, "更新", updateInformation.mUpdateMessage, null, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            downLoadFile(updateInformation.mDownloadUrl);
                        }
                    }).show();
                } else {
                    if (mConfig.mIsShowWaitDialog) {
                        DialogHelper.getOkDialog(mConfig.mActivity, "提示", "已经是新版本了").show();
                    }
                }
            }

            @Override
            public void onFailure(int code, Headers headers, int error, Throwable t) {
                if (mConfig.mIsShowWaitDialog) {
                    mWaitDialog.dismiss();
                    DialogHelper.getOkDialog(mConfig.mActivity, "提示", "网络异常，无法获取新版本信息").show();
                }
            }
        });
    }

    private void downLoadFile(final String downloadURL) {
        if (mConfig.mIsWifiOnly) {
            if (!NetworkUtil.isWifiConnected(mConfig.mActivity)) {
                DialogHelper.getOkCancelDialog(mConfig.mActivity, "更新", "当前网络不是WiFi，是否继续", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        mConfig.mIsWifiOnly = false;
                        downLoadFile(downloadURL);
                    }
                }).show();
                return;
            }
        }
        showProgressUI();
        OkHttpUtil.get(downloadURL, "CheckUpdateManager", new OkHttpResFileHandler(BaseApplication.getAppCacheDir().getAbsolutePath(), "newInstallAPK.apk") {

            @Override
            public void onSuccess(int code, Headers headers, File response) {
                TDevice.installAPK(mConfig.mActivity, mConfig.mAuthorities, response);
                if (mConfig.mIsShowProgressNotification && builder != null && manager != null) {
                    manager.cancel(mConfig.mNotifyId);
                }
                if (mConfig.mIsShowProgressDialog && downloadDialog != null && progressBar != null) {
                    downloadDialog.dismiss();
                }
            }

            @Override
            public void onFailure(int code, Headers headers, int error, Throwable t) {
                MyLogger.d("CheckUpdateManager", "code + " + code + "    errorMessage = " + t.getMessage());
                if (mConfig.mIsShowWaitDialog) {
                    DialogHelper.getOkDialog(mConfig.mActivity, "提示", "下载新版本出错。请重试").show();
                }
                if (mConfig.mIsShowProgressNotification && builder != null && manager != null) {
                    manager.cancel(mConfig.mNotifyId);
                }
                if (mConfig.mIsShowProgressDialog && downloadDialog != null && progressBar != null) {
                    downloadDialog.dismiss();
                }
            }

            @Override
            public void onProgress(long curSize, long totalSize, float progress, boolean done) {
                int precent = (int) (progress * 100);
                if (mConfig.mIsShowProgressNotification && builder != null && manager != null) {
                    builder.setProgress(100, precent, false);
                    manager.notify(mConfig.mNotifyId, builder.build());
                    //下载进度提示
                    builder.setContentText("正在下载" + precent + "%");
                }
                if (mConfig.mIsShowProgressDialog && downloadDialog != null && progressBar != null) {
                    progressBar.setProgress(precent);
                }
            }
        });
    }

    private NotificationCompat.Builder builder;
    private NotificationManager manager;
    private CustomDialog downloadDialog;
    private ProgressBar progressBar;

    private void showProgressUI() {
        if (mConfig.mIsShowProgressNotification) {
            builder = new NotificationCompat.Builder(mConfig.mActivity);
            builder.setContentTitle("下载");
            builder.setContentText("正在下载 0 %");
            manager = (NotificationManager) mConfig.mActivity.getSystemService(Context.NOTIFICATION_SERVICE);
            manager.notify(mConfig.mNotifyId, builder.build());
            builder.setProgress(100, 0, false);
        }
        if (mConfig.mIsShowProgressDialog) {
            View download = UIUtils.getLayoutInflater().inflate(R.layout.layout_dialog_download, null);
            progressBar = (ProgressBar) download.findViewById(R.id.progress);
            downloadDialog = new CustomDialog.Builder()
                    .setCustomView(download)
                    .build();
            downloadDialog.show(mConfig.mActivity.getSupportFragmentManager(), "download_dialog");
        }
    }

    public static class Builder {

        private UpdateManagerConfig config;

        public Builder(AppCompatActivity activity) {
            config = new UpdateManagerConfig(activity);
        }

        public Builder setCheckUrl(String checkUrl) {
            config.mCheckUrl = checkUrl;
            return this;
        }

        public Builder setWifiOnly(boolean isWifiOnly) {
            config.mIsWifiOnly = isWifiOnly;
            return this;
        }

        public Builder setIsShowProgressNotification(boolean isShowProgressNotification) {
            config.mIsShowProgressNotification = isShowProgressNotification;
            return this;
        }

        public Builder setIsShowProgressDialog(boolean isShowProgressDialog) {
            config.mIsShowProgressDialog = isShowProgressDialog;
            return this;
        }

        public Builder setUpdateParse(UpdateInformationParse parse) {
            config.mParse = parse;
            return this;
        }

        public Builder setNotifyId(int notifyId) {
            config.mNotifyId = notifyId;
            return this;
        }

        public CheckUpdateManager build() {
            return newInstance(config);
        }
    }


    public interface UpdateInformationParse {
        UpdateInformation parse(JSONObject source);
    }

    private static class UpdateManagerConfig {
        private AppCompatActivity mActivity;
        private String mCheckUrl;
        private String mAuthorities;
        private boolean mIsWifiOnly = true;
        private boolean mIsShowWaitDialog = true;
        private boolean mIsShowProgressNotification = true;
        private boolean mIsShowProgressDialog = false;
        private UpdateInformationParse mParse;
        private int mNotifyId = NOTIFY_ID;

        public UpdateManagerConfig(AppCompatActivity activity) {
            this.mActivity = activity;
        }
    }

    public static class UpdateInformation {
        public boolean isHasNewVersion;
        public String mDownloadUrl;
        public String mUpdateMessage;
        public boolean isForce;
        public long size;
    }

}